import dao.IFileDAO;
import dao.IUserDAO;
import dao.impl.FileDAOImpl;
import dao.impl.UserDAOImpl;
import pojo.FileItem;
import pojo.User;
import utils.FileUtils;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.util.List;

import static utils.FileUtils.*;

/**
 * 网盘服务器
 */
public class Server {

    private IUserDAO userDAO=new UserDAOImpl();
    private IFileDAO fileDAO=new FileDAOImpl();
    /**
     * 处理文件的查询
     */
    public void handleListFiles(DataInputStream dataInputStream,DataOutputStream dataOutputStream) throws IOException {
        //获得文件集合的JSON
        List<FileItem> uploadFiles = getUploadFiles();
        String json = listToJSON(uploadFiles);
        //发送给客户端
        dataOutputStream.writeUTF(json);

    }

    /**
     *处理文件上传
     *
     */
    public static void handleUpload(DataInputStream dataInputStream,DataOutputStream dataOutputStream) throws IOException{
        //接收文件名
        String fileName= dataInputStream.readUTF();
        if("error".equals(fileName)){
            System.out.println("客户端文件错误");
            return;
        }
        //创建文件输出流
        FileOutputStream fileOutputStream = new FileOutputStream(UPLOAD_DIR+"\\"+fileName);
        //从客户端输入流读取字节，写入到本地文件中
        FileUtils.io(dataInputStream,fileOutputStream);
    }

    /**
     * 处理文件下载
     *
     */
    public static void handleDownload(DataInputStream dataInputStream,DataOutputStream dataOutputStream) throws IOException {
        //接受文件名
        String fileName = dataInputStream.readUTF();
        //判断服务器上是否存在该文件
        File file = new File(UPLOAD_DIR+"\\"+fileName);
        if(file.exists()){
            //如果存在，就发送文件名给客户端
            dataOutputStream.writeUTF(fileName);
            //读取本地磁盘文件，发送给客户端
            FileInputStream fileInputStream = new FileInputStream(file);
            FileUtils.io(fileInputStream,dataOutputStream);
        }else{
            //不存在就发送错误信息
            dataOutputStream.writeUTF("error");
        }
    }

    /**
     *
     * @param dataInputStream
     * @param dataOutputStream
     * @throws IOException
     */
    public static void handleDelete(DataInputStream dataInputStream,DataOutputStream dataOutputStream) throws IOException {
        //接受文件名
        String fileName = dataInputStream.readUTF();
        //判断服务器上是否存在该文件
        File file = new File(UPLOAD_DIR+"\\"+fileName);
        if(file.exists()){
            //如果存在，就发送文件名给客户端
            dataOutputStream.writeUTF(fileName);
            //然后删除该文件
            file.delete();
        }else{
            //不存在就发送错误信息
            dataOutputStream.writeUTF("error");
        }
    }

    public void handleLogin(DataInputStream dataInputStream,DataOutputStream dataOutputStream) throws IOException {
        //接受账号和密码
        String username=dataInputStream.readUTF();
        String password=dataInputStream.readUTF();
        //在数据库中登录验证
        try{
            User user = userDAO.login(username, password);
            if(user==null){
                //用户不存在返回-1
                dataOutputStream.writeLong(-1l);
                return;
            }
            //返回用户ID给客户端
            dataOutputStream.writeLong(user.getId());
        } catch (SQLException e) {
            e.printStackTrace();
        }


    }

    /**
     * 启动服务器
     */
    public void star(){
        System.out.println("网盘服务器启动了");
        //创建服务器Socket
        try(ServerSocket serverSocket = new ServerSocket(PORT)){
            //接收客户端的连接
            for(;;){
                 Socket socket = serverSocket.accept();
                 //获取IO流
                try(DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
                    DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());){
                    //获得客户端的命令类型
                    int type = dataInputStream.readInt();
                    switch (type){
                          case TYPE_LOGIN:
                           System.out.printf("客户端 %s 执行登录\n",socket.getInetAddress());
                           handleLogin(dataInputStream,dataOutputStream);
                             break;
                        case TYPE_LIST:
                            System.out.printf("客户端 %s 执行查询\n",socket.getInetAddress());
                            handleListFiles(dataInputStream,dataOutputStream);
                            break;
                        case TYPE_UPLOAD:
                            System.out.printf("客户端 %s 执行上传\n",socket.getInetAddress());
                            handleUpload(dataInputStream,dataOutputStream);
                            break;
                        case TYPE_DOWNLOAD:
                            System.out.printf("客户端 %s 执行下载\n",socket.getInetAddress());
                            handleDownload(dataInputStream,dataOutputStream);
                            break;
                        case TYPE_DELETE:
                            System.out.printf("客户端 %s 执行删除\n",socket.getInetAddress());
                            handleDelete(dataInputStream,dataOutputStream);
                            break;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        new Server().star();
    }

}
